from io import BytesIO

import requests
from django.contrib.auth.hashers import make_password,check_password
from django.db.models import Q,F
from django.utils.decorators import method_decorator
from rest_framework.views import APIView
from rest_framework.response import Response
from django.conf import settings
from django.http import JsonResponse, HttpResponse



import re
from itsdangerous import TimedJSONWebSignatureSerializer
from .models import Role,User,UserToken,OpenUser
from .serializers import RoleModelSerializer,UserModelSerializer
# Create your views here.

# 用户登录时序列化使用
token_serializers = TimedJSONWebSignatureSerializer(settings.SECRET_KEY,86400)


def is_token(func):
    def wrapper(request,*args,**kwargs):
        token = request.GET.get('token',None)
        if token:
            return func(request,*args,**kwargs)
        else:
            return JsonResponse({'msg':'没有登陆','code':500})
    return wrapper



class RegisterView(APIView):
    """
    author:tutu
    date:2020-6-29
    注册用户
        使用post方法进行数据提交
    """
    def post(self,request):
        print(request.data) # 继承APIView后，可以使用request.data来获取网页提交数据
        username = request.data.get('username')
        password1 = request.data.get('password1')
        password2 = request.data.get('password2')
        phone = request.data.get('phone')
        icon = request.data.get('icon')

        if not re.match('^1[3456789]\d{9}$',phone):
                return Response({'msg':'手机号格式不正确','code':400})
        # 获取数据库中的用户
        user = User.objects.filter(username=username)
        # filter 过滤出来的内容是列表，如获取不到则为空列表
        if user:
            # 条件成立，证明用户已注册
            return Response({'msg':'用户已注册','code':400})
        if password1 == password2:
            data = {
                'username':username,
                'password':make_password(password1),
                'phone':phone,
                'icon':icon
             }

            userSER = UserModelSerializer(data=data)
            # 校验是否成功
            if userSER.is_valid():
                userSER.save()
                return Response({'msg':'OK','code':200})
            else:
                return Response({'error':userSER.errors})
        else:
            return Response({'msg':'两次密码不一致','code':500})



class LoginView(APIView):
    def post(self,request):
        """
        author:tutu
        date:2020-6-29
        注册用户
            使用post方法进行数据提交
        """
        username = request.data.get('username')
        password = request.data.get('password')
        print(username,password)
        # 获取数据库中的用户数据
        # user_obj = User.objects.filter(username=username).first() # first()提取数据为空时，返回None
        user_obj = User.objects.filter(username=username).first()
        # 判断用户是否存在
        if user_obj:
            # 条件成立时，判断密码
            if check_password(password,user_obj.password):
                # 生成token
                user_info = {'user_id':user_obj.pk}
                # 序列化用户信息
                token = token_serializers.dumps(user_info).decode()  # 转成utf-8
                # 把token值存入数据库
                UserToken.objects.update_or_create(user=user_obj,defaults={'token':token})
                # 返回
                return Response({'msg':'OK','code':200,'token':token,'username':username})
            else:
                return Response({'msg':'用户名或密码不正确','code':400})
        else:
            return Response({'msg':'用户名或密码不正确','code':401})



# @method_decorator(is_token,name='dispatch')
class Home(APIView):
    # request.path_info
    # /user/userinfo/
    # /user/cart/
    def get(self,request):
        return Response({'msg':'OK','code':200})


class WeiboView(APIView):
    def get(self, request):
        # 获取 传递来的code
        code = request.GET.get("code")
        print("code:%s" % code)

        data = {
            "client_id": "2682391216",
            "client_secret": "6617bc33ba750d4bc6906da3644288aa",
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": "http://127.0.0.1:8080/weibo",
        }

        # 进行网络请求操作
        r = requests.post("https://api.weibo.com/oauth2/access_token", data)
        print(r.json())
        uid = r.json()["uid"]
        access_token = r.json()["access_token"]

        # 测试根据访问令牌access_token拿到用户信息
        r = requests.get("https://api.weibo.com/2/users/show.json", {"access_token": access_token, "uid": uid})
        print(r.json())

        return Response({"msg": "OK"})


class WeiboView1(APIView):
    def get(self, request):
        # 获取传递来的code
        code = request.GET.get("code")
        print("code:", code)

        data = {
            "client_id": "2682391216",
            "client_secret": "6617bc33ba750d4bc6906da3644288aa",
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": "http://127.0.0.1:8080/weibo",
        }
        r = requests.post("https://api.weibo.com/oauth2/access_token", data=data)
        print(
            r.json())
        # {'access_token': '2.00cxoM_DTI7yPD4a245834fc8p6RNC', 'remind_in': '157679999', 'expires_in': 157679999, 'uid': '3032204712', 'isRealName': 'true'}
        uid = r.json().get("uid")
        if not uid:
            return Response({"msg": "微博登录失败"}, status=401)
        access_token = r.json()["access_token"]

        print("uid", uid)
        print("access_token:", access_token)

        # 保存 微博账号到我们的 OpenUser中   get_or_create  先去查找 查找到了就返回，查找不对就添加

        open_user = OpenUser.objects.filter(uid=uid).first()
        if not open_user:
            # 数据表中不存在， 则插入 第三方账号  绑定的用户这里不写，让用户去输入
            OpenUser.objects.create(uid=uid, type=1)
            return Response({"msg": "登录成功", "code": 202, "uid": uid})  # code 202 表示 还需要进一步让用户绑定账号
        return Response({"msg": "登录成功", "code": 200})



class BindView(APIView):
    def post(self,request):
        username = request.data.get('username')
        password = request.data.get('password')
        uid = request.data.get('uid')

        user = User.objects.filter(username=username,password=password).first()
        if user:
            OpenUser.objects.filter(uid=uid).update({'user_id':user.id})

            return Response({'msg':'绑定成功'})
        else:
            return Response({'msg':'本地账号不存在，请重新输入','code':401})


def make_image_code(request):
    from PIL import Image, ImageDraw, ImageFont
    import random
    import string
    # 生成画布
    image = Image.new("RGB", (100, 40), "yellow")
    # 创建一个画笔 来绘画
    draw = ImageDraw.Draw(image)
    # 创建一个图片字体

    font = ImageFont.truetype("simsun.ttc", size=30)

    # 生成一个随机6位字符串
    r = random.sample(string.digits + string.ascii_letters, 4)

    # 列表拼接成字符串
    words = "".join(r)

    # 绘制一个字符串到画布上
    draw.text((10, 10), text=words, fill="red", font=font)

    # 显示
    # image.show()
    # 创建一个字节流对象
    fp = BytesIO()
    # 图片数据写入到字节流内
    image.save(fp,"png")
    # 从字节流中 读取数据
    data = fp.getvalue()

    return HttpResponse(data,content_type="image/png")